# -*- coding:utf-8 -*-

# @Time    : 2023/5/3 21:10
# @Author  : zengwenjia
# @Email   : zengwenjia@lingxi.ai
# @File    : generate_utterance_template.py
# @Software: LLM_internal

# # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # # #
import os
import utils
import time
import openai
import re

openai.api_key = "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"

prompt = """
被要求构建一个退休规划任务。这个任务将被提供给GPT模型，我们将评估GPT模型完成任务的能力，这个任务有部分信息缺省，你需要填充{}里的信息，并给出这个任务的结果。
以下是你提供任务需要满足的要求：
1.任务包含指令、答案两部分。任务的结果是答案，指令是指导模型完成任务的信息。任务的结果单独一行，指令和任务两者之间用######号分隔。
2.你需要把任务中{conversation_history}、{conversation_stage}都用实际内容替换掉
3.{conversation_history}是用户和退休规划师的对话内容，退休规划师的回答是"退休规划师:"开头，用户的回复是"用户:"开头，用户和退休规划师的对话交替进行，最后一句是"退休规划师:"开头的,没有内容，内容是需要你在答案中给出
4.{conversation_history}是基于电话媒介的，内容尽可能多样、丰富、口语化和完整。
5.{conversation_stage}是接下来生成对话阶段，需要根据当前的对话阶段生成话术。
6.你需要确保{conversation_history}、{conversation_stage}不被遗漏替换且被正确替换，且能输出正确的任务结果
7.任务的结果用"######"分割，以"答案:"开头

具体的任务如下，你需要填充{}里的信息，并给出这个任务的结果：
    请不要忘记，你是一名退休规划师。你在一家名叫零犀一点通的公司工作。
            零犀一点通的业务是：为用户提供全面的退休服务。我们专注于帮助客户制定和实施个性化的退休策略，以满足他们在不同生活阶段的需求。
            公司的价值观是：真诚、温暖、专业，做用户的真朋友。
            用户当前和你沟通的方式是微信。
            请保持简短的回答内容以保持用户的注意力，不要列出清单，只回答问题。
            你必须根据以前的会话历史和当前的会话阶段做出回应。每次只生成一个回复！
            当前会话阶段：{conversation_stage}
            会话历史：
            {conversation_history}
            退休规划师:

示例：
请不要忘记，你是一名退休规划师。你在一家名叫零犀一点通的公司工作。
            零犀一点通的业务是：为用户提供全面的退休服务。我们专注于帮助客户制定和实施个性化的退休策略，以满足他们在不同生活阶段的需求。
            公司的价值观是：真诚、温暖、专业，做用户的真朋友。
            用户当前和你沟通的方式是微信。
            请保持简短的回答内容以保持用户的注意力，不要列出清单，只回答问题。
            你必须根据以前的会话历史和当前的会话阶段做出回应。每次只生成一个回复！
            当前会话阶段：设定目标：与客户一起确定提前退休的目标，包括退休年龄、预期的生活水平和其他退休目标。确保目标具体、可衡量并真实可行。
            会话历史：
            退休规划师:您好，我是您的退休规划师。感谢您选择零犀一点通。请问有什么我可以帮助您的吗？
用户:我想提前退休
退休规划师:了解，提前退休是很多人的梦想。能否告诉我您现在的年龄，以及您的退休计划是什么时候？这有助于我们更好地为您制定个性化的退休策略。
用户:我现在35岁，我想55岁退休
退休规划师:了解，那么您希望在退休后的生活水平是什么样子的呢？我们需要确保目标具体、可衡量并真实可行。
用户:我想在二线城市生活，每年可以旅游
            退休规划师:

######
答案：好的，那么您希望每年旅游的预算大概是多少呢？我们需要确保目标具体、可衡量并真实可行。同时，我们也会为您提供更多关于二线城市生活的信息和建议。

根据示例，你需要填充{}里的信息，并给出这个任务的结果：
"""


# 判断是否是标准输出
def find_standard_output(answer_list, result):
    for answer in answer_list:
        if answer in result:
            return answer
    return ""


def generate_instruction_following_data(
        output_path="../data_set/reading_comprehension/common_determine_utterance.json",
        num_instructions_to_generate=1500,  # 6000, 8000
        model_name="gpt-3.5-turbo",
        temperature=0.9,
):
    machine_instruction_data = []
    if os.path.exists(output_path):
        machine_instruction_data = utils.jload(output_path)
        print(f"Loaded {len(machine_instruction_data)} machine-generated instructions")

    request_idx = 0
    while len(machine_instruction_data) < num_instructions_to_generate:
        request_idx += 1

        start_time = time.time()

        completion = openai.ChatCompletion.create(model=model_name, temperature=temperature, messages=[
            {"role": "system", "content": "你是一名专业的退休规划师。"},
            {"role": "user","content": prompt}])

        result = completion.choices[0].message.content
        print(f"Completion #{request_idx} took {time.time() - start_time:.2f}s")
        answer_list = ["答案：", "结果：", "答案:", "结果:", "结果为：", "答案为：", "结果为:", "答案为:"]
        answer = find_standard_output(answer_list, result)
        if answer and ("{conversation_history}" not in result) and ("{conversation_stage}" not in result):
            result = result.replace(answer, "答案：")
            contents = result.split("答案：")
            instruct_content = contents[0].replace("######", "")
            output = contents[1]
            # if output not in instruct_content:
            #     print("No answer found, skipping:")
            #     print(f"result is " + result + "\n")
            #     continue

            # 通过正则表达式提取output里数字
            machine_instruction_data.append({"instruction": instruct_content, "input": "", "output": output})
            utils.jdump(machine_instruction_data, output_path)
        else:
            print("No answer found, skipping:")
            print(f"result is " + result + "\n")
            continue


if __name__ == "__main__":
    generate_instruction_following_data()